#include "menu.h"
#include "mutex.h"
#include "stdbool.h"
#include "stdio.h"
#include "stdlib.h"
#include "stm32f1xx_hal_gpio.h"
#include "task.h"
#include "log.h"

const static char *TAG = "menu";

#if MENU_SELECT

#define SPEED 4 // 16的因数
#define ICON_SPEED 12
#define ICON_SPACE 48 // 图标间隔，speed倍数

void chart_draw_frame(u8g2_t *u8g2);

// main界面图片
const uint8_t DOGE[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00, 0x0D, 0x00,
    0x00, 0x00, 0x00, 0x06, 0x00, 0x80, 0x08, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x40, 0x08, 0x00,
    0x00, 0x00, 0x00, 0x08, 0x00, 0x20, 0x08, 0x00, 0x00, 0x00, 0x20, 0x08, 0x00, 0x10, 0x08, 0x00,
    0x00, 0x00, 0x20, 0x10, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x20, 0x10, 0x00, 0x0C, 0x08, 0x00,
    0x00, 0x00, 0x20, 0xE0, 0x07, 0x06, 0x08, 0x00, 0x00, 0x00, 0x20, 0x00, 0xF8, 0x01, 0x08, 0x00,
    0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x08, 0x00,
    0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00,
    0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
    0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00,
    0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x04, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00,
    0x00, 0x04, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x02, 0x0E, 0x00, 0x00, 0x00, 0x40, 0x00,
    0x00, 0x02, 0x06, 0x80, 0x07, 0x00, 0x40, 0x00, 0x00, 0x01, 0x02, 0x40, 0x0F, 0x00, 0xC0, 0x00,
    0x00, 0x01, 0x00, 0x20, 0x1F, 0x00, 0x80, 0x00, 0x80, 0x01, 0x00, 0x20, 0x0F, 0x00, 0x80, 0x00,
    0x80, 0x00, 0x00, 0x00, 0x07, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01,
    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x01,
    0x80, 0xF0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0xF0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x01,
    0x40, 0xE0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xE0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01,
    0x80, 0xE0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0xC0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
    0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
    0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0xE1, 0x03, 0x00, 0x00, 0x00, 0x80, 0x00,
    0x00, 0xE1, 0x1F, 0x18, 0x00, 0x00, 0x80, 0x00, 0x00, 0x81, 0xFF, 0x0F, 0x00, 0x00, 0x40, 0x00,
    0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00,
    0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
    0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00,
    0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
    0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xC0, 0x00, 0x00,
    0x00, 0x00, 0x06, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00,
    0x00, 0x00, 0x60, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0xC0, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0xFC, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

uint8_t disappear_step = 1;

// 温湿度数据记录
float angle_humi, angle_last_humi, angle_temp, angle_last_temp;
// 实时坐标
uint8_t chart_x_humi, chart_x_temp;
bool frame_is_drawed = false;

// 指向buf首地址的指针
uint8_t *buf_ptr;
uint16_t buf_len;

// 选择界面变量
uint8_t x;
int16_t y, y_trg;                 // 目标和当前
uint8_t line_y, line_y_trg;       // 线的位置
uint8_t box_width, box_width_trg; // 框的宽度
int16_t box_y, box_y_trg;         // 框的当前值和目标值
int8_t ui_select;                 // 当前选中那一栏

// 界面变量
uint8_t ui_index, ui_state;

enum // ui_index
{
    M_POP,       // M_POP
    M_LOGO,      // 开始界面
    M_SELECT,    // 选择界面
    M_CHART,     // 图表
    M_TEXT_EDIT, // 文字编辑
    M_ABOUT,     // 关于本机
};

enum // ui_state
{
    S_NONE,
    S_DISAPPEAR,
    S_SWITCH,
    S_MENU_TO_MENU,
    S_MENU_TO_PIC,
    S_PIC_TO_MENU,
};

// 菜单结构体
struct SELECT_LIST
{
    char *select;
};

// 选择界面列表
struct SELECT_LIST list[] =
    {
        {"MainUI"},
        {"-Chart DHT11"},
        {"-Threshold Edit"},
        {"-About"},
        {"-POP"},
};

#define list_num 5                         // 选择界面数量
#define single_line_length (63 / list_num) // 单独一行高度
uint8_t total_line_length = single_line_length * list_num + 1;

char text_name[] = "27"; /*设置阈值的大小*/
// 允许名字的最大长度
const uint8_t text_name_len = 2; // 0-11for text_name  12 for return
uint8_t edit_index = 0;
bool edit_flag = false;         // 默认不在编辑
uint8_t blink_flag;             // 默认高亮
const uint8_t BLINK_SPEED = 16; // 2的倍数

// 按键变量
typedef struct
{
    bool val;
    bool last_val;
} KEY;

KEY key[3] = {false};

// 按键信息
typedef struct
{
    uint8_t id;
    bool pressed;
} KEY_MSG;

KEY_MSG key_msg = {0};

/**
 * @brief Get the key val object
 *
 * @param ch
 * @return true
 * @return false
 */
bool get_key_val(uint8_t ch)
{
    switch (ch)
    {
    case 0:
        return HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_4); // up
    case 1:
        return HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_6); // enter
    case 2:
        return HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_5); // down
    default:
        return false;
    }
}

/**
 * @brief key_scan
 *
 */
void key_scan(void)
{
    for (uint8_t i = 0; i < (sizeof(key) / sizeof(KEY)); ++i)
    {
        key[i].val = get_key_val(i);       // 获取键值
        if (key[i].last_val != key[i].val) // 发生改变
        {
            key[i].last_val = key[i].val; // 更新状态
            if (key[i].val == 0)
            {
                key_msg.id = i;
                key_msg.pressed = true;
            }
        }
    }
}

/**
 * @brief move 移动函数
 *
 * @param a
 * @param a_trg
 * @return true
 * @return false
 */
bool move(int16_t *a, int16_t *a_trg)
{
    if (*a < *a_trg)
    {
        *a += SPEED;
        if (*a > *a_trg)
            *a = *a_trg; // 加完超过
    }
    else if (*a > *a_trg)
    {
        *a -= SPEED;
        if (*a < *a_trg)
            *a = *a_trg; // 减完不足
    }
    else
    {
        return true; // 到达目标
    }
    return false; // 未到达
}

/**
 * @brief move_width 宽度移动函数
 *
 * @param u8g2
 * @param a
 * @param a_trg
 * @param select
 * @param id
 * @return true
 * @return false
 */
bool move_width(u8g2_t *u8g2, uint8_t *a, uint8_t *a_trg, uint8_t select, uint8_t id)
{
    if (*a < *a_trg)
    {
        uint8_t step = 16 / SPEED; // 判断步数
        uint8_t len;
        if (ui_index == M_SELECT)
        {
            len = abs(u8g2_GetStrWidth(u8g2, list[select].select) - u8g2_GetStrWidth(u8g2, list[id == 0 ? select + 1 : select - 1].select));
        }

        uint8_t width_speed = ((len % step) == 0 ? (len / step) : (len / step + 1)); // 计算步长
        *a += width_speed;
        if (*a > *a_trg)
            *a = *a_trg; //
    }
    else if (*a > *a_trg)
    {
        uint8_t step = 16 / SPEED; // 判断步数
        uint8_t len;
        if (ui_index == M_SELECT)
        {
            len = abs(u8g2_GetStrWidth(u8g2, list[select].select) - u8g2_GetStrWidth(u8g2, list[id == 0 ? select + 1 : select - 1].select));
        }

        uint8_t width_speed = ((len % step) == 0 ? (len / step) : (len / step + 1)); // 计算步长
        *a -= width_speed;
        if (*a < *a_trg)
            *a = *a_trg;
    }
    else
    {
        return true; // 到达目标
    }
    return false; // 未到达
}

/**
 * @brief move_bar 进度条移动函数
 *
 * @param a
 * @param a_trg
 * @return true
 * @return false
 */
bool move_bar(uint8_t *a, uint8_t *a_trg)
{
    if (*a < *a_trg)
    {
        uint8_t step = 16 / SPEED;                                                                                                // 判断步数
        uint8_t width_speed = ((single_line_length % step) == 0 ? (single_line_length / step) : (single_line_length / step + 1)); // 计算步长
        *a += width_speed;
        if (*a > *a_trg)
            *a = *a_trg; //
    }
    else if (*a > *a_trg)
    {
        uint8_t step = 16 / SPEED;                                                                                                // 判断步数
        uint8_t width_speed = ((single_line_length % step) == 0 ? (single_line_length / step) : (single_line_length / step + 1)); // 计算步长
        *a -= width_speed;
        if (*a < *a_trg)
            *a = *a_trg;
    }
    else
    {
        return true; // 到达目标
    }
    return false; // 未到达
}

/**
 * @brief text_edit 文字编辑函数
 *
 * @param dir
 * @param index
 */
void text_edit(bool dir, uint8_t index, menu_threshold_t *threshold)
{
    if (!dir)
    {
        if (text_name[index] >= '0' && text_name[index] <= '9')
        {
            if (text_name[index] == '9')
            {
                text_name[index] = '0';
            }
            else
            {
                text_name[index] -= 1;
            }
        }
        else
        {
            text_name[index] = '0';
        }
    }
    else
    {
        if (text_name[index] >= '0' && text_name[index] <= '9')
        {
            if (text_name[index] >= '9')
            {
                text_name[index] = '0';
            }
            else
            {
                text_name[index] += 1;
            }
        }
        else
        {
            text_name[index] = '0';
        }
    }
    threshold->temp = atof(text_name);                  // 初始化阈值
    MY_LOGI(TAG, "text_name: %d\r\n", threshold->temp); // 打印阈值
}

/**
 * @brief disappear 消失函数
 *
 */
void disappear()
{
    switch (disappear_step)
    {
    case 1:
        for (uint16_t i = 0; i < buf_len; ++i)
        {
            if (i % 2 == 0)
                buf_ptr[i] = buf_ptr[i] & 0x55;
        }
        break;
    case 2:
        for (uint16_t i = 0; i < buf_len; ++i)
        {
            if (i % 2 != 0)
                buf_ptr[i] = buf_ptr[i] & 0xAA;
        }
        break;
    case 3:
        for (uint16_t i = 0; i < buf_len; ++i)
        {
            if (i % 2 == 0)
                buf_ptr[i] = buf_ptr[i] & 0x00;
        }
        break;
    case 4:
        for (uint16_t i = 0; i < buf_len; ++i)
        {
            if (i % 2 != 0)
                buf_ptr[i] = buf_ptr[i] & 0x00;
        }
        break;
    default:
        ui_state = S_NONE;
        disappear_step = 0;
        break;
    }
    disappear_step++;
}

/**************************界面显示*******************************/

/**
 * @brief logo_ui_show 显示logo
 *
 * @param u8g2
 */
void logo_ui_show(u8g2_t *u8g2)
{
    u8g2_DrawXBMP(u8g2, 32, 0, 64, 64, DOGE);
}

/**
 * @brief select_ui_show 选择界面
 *
 * @param u8g2
 */
void select_ui_show(u8g2_t *u8g2)
{
    move_bar(&line_y, &line_y_trg);
    move(&y, &y_trg);
    move(&box_y, &box_y_trg);
    move_width(u8g2, &box_width, &box_width_trg, ui_select, key_msg.id);
    u8g2_DrawVLine(u8g2, 126, 0, total_line_length);
    u8g2_DrawPixel(u8g2, 125, 0);
    u8g2_DrawPixel(u8g2, 127, 0);
    for (uint8_t i = 0; i < list_num; ++i)
    {
        u8g2_DrawStr(u8g2, x, 16 * i + y + 12, list[i].select); // 第一段输出位置
        u8g2_DrawPixel(u8g2, 125, single_line_length * (i + 1));
        u8g2_DrawPixel(u8g2, 127, single_line_length * (i + 1));
    }
    u8g2_DrawVLine(u8g2, 125, line_y, single_line_length - 1);
    u8g2_DrawVLine(u8g2, 127, line_y, single_line_length - 1);
    u8g2_SetDrawColor(u8g2, 2);
    u8g2_DrawRBox(u8g2, 0, box_y, box_width, 16, 1);
    u8g2_SetDrawColor(u8g2, 1);
}

/**
 * @brief chart_ui_show chart界面
 *
 * @param u8g2
 * @param dht_data
 */
void chart_ui_show(u8g2_t *u8g2, dht_t *dht_data)
{
    if (!frame_is_drawed) // 框架只画一遍
    {
        u8g2_ClearBuffer(u8g2);
        chart_draw_frame(u8g2);
        angle_last_humi = dht_data->humi / 2;
        angle_last_temp = dht_data->temp / 2;
        frame_is_drawed = true;
    }

    u8g2_DrawBox(u8g2, 0, 0, 30, 14); /*  */

    /* 湿度chart */
    u8g2_DrawVLine(u8g2, chart_x_humi + 10, 59, 3);
    u8g2_DrawVLine(u8g2, chart_x_temp + 74, 59, 3);
    if (chart_x_humi == 40)
        chart_x_humi = 0;
    if (chart_x_temp == 40)
        chart_x_temp = 0;
    u8g2_DrawVLine(u8g2, chart_x_humi + 11, 24, 34);
    u8g2_DrawVLine(u8g2, chart_x_humi + 12, 24, 34);
    u8g2_DrawVLine(u8g2, chart_x_humi + 13, 24, 34);
    u8g2_DrawVLine(u8g2, chart_x_humi + 14, 24, 34);
    u8g2_DrawVLine(u8g2, chart_x_temp + 75, 24, 34);
    u8g2_DrawVLine(u8g2, chart_x_temp + 76, 24, 34);
    u8g2_DrawVLine(u8g2, chart_x_temp + 77, 24, 34);
    u8g2_DrawVLine(u8g2, chart_x_temp + 78, 24, 34);
    u8g2_SetDrawColor(u8g2, 2);
    angle_humi = dht_data->humi / 2;
    angle_temp = dht_data->temp / 2;
    u8g2_DrawLine(u8g2, chart_x_humi + 11, 58 - (int)angle_last_humi / 2, chart_x_humi + 12, 58 - (int)angle_humi / 2);
    u8g2_DrawLine(u8g2, chart_x_temp + 75, 58 - (int)angle_last_temp / 2, chart_x_temp + 76, 58 - (int)angle_temp / 2);
    u8g2_DrawVLine(u8g2, chart_x_humi + 12, 59, 3);
    u8g2_DrawVLine(u8g2, chart_x_temp + 76, 59, 3);
    angle_last_humi = angle_humi;
    angle_last_temp = angle_temp;
    chart_x_humi += 2;
    chart_x_temp += 2;

    u8g2_DrawBox(u8g2, 0, 0, 30, 14);

    u8g2_SetDrawColor(u8g2, 1); /*  */

    /* 显示温湿度*/
    if (xSemaphoreTake(dht_mutex, 0) == pdTRUE) // 获取dht的互斥锁 -- 这种是不阻塞
    {
        /*访问共享资源-dht温湿度*/
        // u8g2_DrawBitmap(u8g2, 0, 0, 20, 14, bitmap);
        char str[22];
        sprintf(str, "Humi:%.1f%% Temp:%.1fC", dht_data->humi, dht_data->temp);
        u8g2_DrawStr(u8g2, 2, 12, str);
        xSemaphoreGive(dht_mutex); // 释放互斥锁
    }
}

/**
 * @brief chart_draw_frame chart界面画布
 *
 * @param u8g2
 */
void chart_draw_frame(u8g2_t *u8g2)
{
    u8g2_DrawRBox(u8g2, 0, 18, 60, 46, 8);
    u8g2_DrawRBox(u8g2, 64, 18, 60, 46, 8);
    u8g2_SetDrawColor(u8g2, 2);

    // box line 1
    u8g2_DrawHLine(u8g2, 4, 58, 50); // x
    u8g2_DrawVLine(u8g2, 4, 24, 34); // y
    // box line 2
    u8g2_DrawHLine(u8g2, 68, 58, 50); // x
    u8g2_DrawVLine(u8g2, 68, 24, 34); // y
    // 箭头1
    u8g2_DrawPixel(u8g2, 1, 27);
    u8g2_DrawPixel(u8g2, 2, 26);
    u8g2_DrawPixel(u8g2, 3, 25);
    u8g2_DrawPixel(u8g2, 53, 59);
    u8g2_DrawPixel(u8g2, 52, 60);
    u8g2_DrawPixel(u8g2, 51, 61);
    // 箭头2
    u8g2_DrawPixel(u8g2, 65, 27);
    u8g2_DrawPixel(u8g2, 66, 26);
    u8g2_DrawPixel(u8g2, 67, 25);
    u8g2_DrawPixel(u8g2, 117, 59);
    u8g2_DrawPixel(u8g2, 116, 60);
    u8g2_DrawPixel(u8g2, 115, 61);

    u8g2_SetDrawColor(u8g2, 1);
}

/**
 * @brief text_edit_ui_show 编辑界面
 *
 * @param u8g2
 */
void text_edit_ui_show(u8g2_t *u8g2)
{
    u8g2_DrawRFrame(u8g2, 4, 6, 120, 52, 8);
    u8g2_DrawStr(u8g2, (128 - u8g2_GetStrWidth(u8g2, "-Threshold Editor-")) / 2, 20, "-Threshold Editor-");
    u8g2_DrawStr(u8g2, 10, 38, text_name);
    u8g2_DrawStr(u8g2, 80, 50, "-Return");

    uint8_t box_x = 9;

    // 绘制光标
    if (edit_index < text_name_len)
    {
        if (blink_flag < BLINK_SPEED / 2)
        {
            for (uint8_t i = 0; i < edit_index; ++i)
            {
                char temp[2] = {text_name[i], '\0'};
                box_x += u8g2_GetStrWidth(u8g2, temp);
                if (text_name[i] != ' ')
                {
                    box_x++;
                }
            }
            char temp[2] = {text_name[edit_index], '\0'};
            u8g2_SetDrawColor(u8g2, 2);
            u8g2_DrawBox(u8g2, box_x, 26, u8g2_GetStrWidth(u8g2, temp) + 2, 16);
            u8g2_SetDrawColor(u8g2, 1);
        }
    }
    else
    {
        u8g2_SetDrawColor(u8g2, 2);
        u8g2_DrawRBox(u8g2, 78, 38, u8g2_GetStrWidth(u8g2, "-Return") + 4, 16, 1);
        u8g2_SetDrawColor(u8g2, 1);
    }

    if (edit_flag) // 处于编辑状态
    {
        if (blink_flag < BLINK_SPEED)
        {
            blink_flag += 1;
        }
        else
        {
            blink_flag = 0;
        }
    }
    else
    {
        blink_flag = 0;
    }
}

/**
 * @brief about_ui_show about界面
 *
 * @param u8g2
 */
void about_ui_show(u8g2_t *u8g2)
{
    u8g2_DrawStr(u8g2, 2, 12, "MCU : STM32F1xRCT6");
    u8g2_DrawStr(u8g2, 2, 28, "FLASH : 256KB");
    u8g2_DrawStr(u8g2, 2, 44, "SRAM : 48KB");
    u8g2_DrawStr(u8g2, 2, 60, "CPU frequency : 72M");
}

/**
 * @brief pop_ups_show 弹窗
 *
 * @param u8g2
 */
void pop_ups_show(u8g2_t *u8g2)
{
    u8g2_DrawRBox(u8g2, 34, 20, 60, 30, 4);
    u8g2_SetDrawColor(u8g2, 0);
    u8g2_DrawStr(u8g2, 51, 38, "Check");
    u8g2_SetDrawColor(u8g2, 1);
}

/**************************界面处理*******************************/

/**
 * @brief pop_ups_proc 弹窗界面处理
 *
 * @param u8g2
 */
void pop_ups_proc(u8g2_t *u8g2)
{
    if (key_msg.pressed)
    {
        key_msg.pressed = false;
        ui_state = S_DISAPPEAR;
        ui_index = M_POP;
    }
    // u8g2_ClearBuffer(u8g2);
    pop_ups_show(u8g2);
    // u8g2_SendBuffer(u8g2);

    vTaskDelay(1000);

    ui_state = S_DISAPPEAR;
    ui_index = M_CHART;
}

/**
 * @brief logo_proc logo界面处理函数
 *
 * @param u8g2
 */
void logo_proc(u8g2_t *u8g2) //
{
    if (key_msg.pressed)
    {
        key_msg.pressed = false;
        ui_state = S_DISAPPEAR;
        ui_index = M_SELECT;
    }
    logo_ui_show(u8g2);
}

/**
 * @brief select_proc 选择界面处理
 *
 * @param u8g2
 */
void select_proc(u8g2_t *u8g2) //
{
    if (key_msg.pressed)
    {
        key_msg.pressed = false;
        switch (key_msg.id)
        {
        case 0:
            if (ui_select < 1)
                break;
            ui_select -= 1;
            line_y_trg -= single_line_length;
            if (ui_select < -(y / 16))
            {
                y_trg += 16;
            }
            else
            {
                box_y_trg -= 16;
            }

            break;
        case 1:
            if ((ui_select + 2) > (sizeof(list) /* / sizeof(SELECT_LIST)*/))
                break;
            ui_select += 1;
            line_y_trg += single_line_length;
            if ((ui_select + 1) > (4 - y / 16))
            {
                y_trg -= 16;
            }
            else
            {
                box_y_trg += 16;
            }

            break;
        case 2:
            switch (ui_select)
            {
            case 0: // return
                ui_state = S_DISAPPEAR;
                ui_index = M_LOGO;
                break;
            case 1: // chart
                ui_state = S_DISAPPEAR;
                ui_index = M_CHART;
                break;
            case 2: // textedit
                ui_state = S_DISAPPEAR;
                ui_index = M_TEXT_EDIT;
                break;
            case 3: // about
                ui_state = S_DISAPPEAR;
                ui_index = M_ABOUT;
                break;
            case 4: // about
                ui_state = S_DISAPPEAR;
                ui_index = M_POP;
                break;
            default:
                break;
            }
        // Serial.println("Btn2");
        default:
            break;
        }
        // Serial.println(ui_select);
        box_width_trg = u8g2_GetStrWidth(u8g2, list[ui_select].select) + x * 2;
    }
    select_ui_show(u8g2);
}

/**
 * @brief chart_proc chart界面处理函数
 *
 * @param u8g2
 * @param dht_data
 */
void chart_proc(u8g2_t *u8g2, dht_t *dht_data) //
{
    chart_ui_show(u8g2, dht_data);
    if (key_msg.pressed)
    {
        key_msg.pressed = false;
        ui_state = S_DISAPPEAR;
        ui_index = M_SELECT;
        frame_is_drawed = false; // 退出后框架为未画状态
        chart_x_humi = 0;
        chart_x_temp = 0;
    }
}

/**
 * @brief text_edit_proc 文本编辑处理函数
 *
 * @param u8g2
 */
void text_edit_proc(u8g2_t *u8g2, menu_threshold_t *threshold)
{
    text_edit_ui_show(u8g2);
    if (key_msg.pressed)
    {
        key_msg.pressed = false;
        switch (key_msg.id)
        {
        case 0:
            if (edit_flag)
            {
                // 编辑
                text_edit(false, edit_index, threshold);
            }
            else
            {
                if (edit_index == 0)
                {
                    edit_index = text_name_len;
                }
                else
                {
                    edit_index -= 1;
                }
            }
            break;
        case 1:
            if (edit_flag)
            {
                // 编辑
                text_edit(true, edit_index, threshold);
            }
            else
            {
                if (edit_index == text_name_len)
                {
                    edit_index = 0;
                }
                else
                {
                    edit_index += 1;
                }
            }
            break;
        case 2:
            if (edit_index == text_name_len)
            {
                ui_state = S_DISAPPEAR;
                ui_index = M_SELECT;
                edit_index = 0;
            }
            else
            {
                edit_flag = !edit_flag;
            }
            break;
        default:
            break;
        }
    }
}

/**
 * @brief about_proc about界面处理函数
 *
 * @param u8g2
 */
void about_proc(u8g2_t *u8g2)
{
    if (key_msg.pressed)
    {
        key_msg.pressed = false;
        ui_state = S_DISAPPEAR;
        ui_index = M_SELECT;
    }
    about_ui_show(u8g2);
}

/********************************总的UI显示************************************/

/**
 * @brief ui_proc 总的UI进程
 *
 * @param u8g2
 * @param dht_data
 */
void ui_proc(u8g2_t *u8g2, dht_t *dht_data, menu_threshold_t *threshold)
{
    switch (ui_state)
    {
    case S_NONE:
        if (ui_index != M_CHART)
            u8g2_ClearBuffer(u8g2);
        switch (ui_index)
        {
        case M_POP:
            pop_ups_proc(u8g2);
            break;
        case M_LOGO:
            logo_proc(u8g2);
            break;
        case M_SELECT:
            select_proc(u8g2);
            break;
        case M_CHART:
            chart_proc(u8g2, dht_data);
            break;
        case M_TEXT_EDIT:
            text_edit_proc(u8g2, threshold);
            break;
        case M_ABOUT:
            about_proc(u8g2);
            break;
        default:
            break;
        }
        break;
    case S_DISAPPEAR:
        disappear();
        break;
    default:
        break;
    }
    u8g2_SendBuffer(u8g2);
}

/**
 * @brief menu_init menu初始化
 *
 * @param u8g2
 */
void menu_init(u8g2_t *u8g2)
{
    u8g2_SetFont(u8g2, u8g2_font_wqy12_t_chinese1);

    buf_ptr = u8g2_GetBufferPtr(u8g2); // 拿到buffer首地址
    buf_len = 8 * u8g2_GetBufferTileHeight(u8g2) * u8g2_GetBufferTileWidth(u8g2);

    x = 4;
    y = y_trg = 0;
    line_y = line_y_trg = 1;

    box_width = box_width_trg = u8g2_GetStrWidth(u8g2, list[ui_select].select) + x * 2; // 两边各多2

    // ui_index = M_LOGO;
    // ui_index = M_CHART; /* 默认启动界面 */
    ui_index = M_POP; /* 弹窗 */
    ui_state = S_NONE;
}

#else

/**
 * @brief 按键结构体
 */
typedef struct
{
    uint8_t current;         // 当前组索引号
    uint8_t down;            // 下翻索引号
    uint8_t enter;           // 确认索引号
    void (*operation)(void); // 动作
} key_table_t;

key_table_t table[];

uint8_t key[2] = {0};

/**
 * @brief ɨ
 * @param None
 * @retval None
 */
void key_scan(void)
{
    static uint8_t flag[2] = {0};
    uint8_t value[2];
    uint8_t i;

    value[0] = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_5);
    value[1] = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_6);

    for (i = 0; i < 2; i++)
    {
        if (flag[i] == 0 && value[i] == 0)
        {
            flag[i] = 1;
        }
        if (flag[i] == 1 && value[i] == 1)
        {
            key[i] = 1;
            flag[i] = 0;
        }
    }
}

/**
 * @brief 菜单
 * @param None
 * @retval None
 */
void main_menu(void)
{
    static uint8_t index = 0;

    // 确认
    if (key[0] == 1)
    {
        index = table[index].enter;
        key[0] = 0;
    }
    // 下一个
    if (key[1] == 1)
    {
        index = table[index].down;
        key[1] = 0;
    }

    if (table[index].operation != NULL)
    {
        table[index].operation();
    }
}

/**
 * @brief 欢迎界面
 * @param None
 * @retval None
 */
void start_gui(void)
{
    // OLED_ShowString(1, 1, "user help:      ", 0);
    // OLED_ShowString(2, 1, "key1 -> down    ", 0);
    // OLED_ShowString(3, 1, "key0 -> ensure  ", 0);
    // OLED_ShowString(4, 1, "continue...     ", 0);
}

/**
 * @brief 项
 * @param None
 * @retval None
 */
void gui_a(void)
{
    // OLED_ShowString(1, 1, "weater          ", 1);
    // OLED_ShowString(2, 1, "music           ", 0);
    // OLED_ShowString(3, 1, "device          ", 0);
    // OLED_ShowString(4, 1, "return          ", 0);
}

/**
 * @brief 项
 * @param None
 * @retval None
 */
void gui_b(void)
{
    // OLED_ShowString(1, 1, "weater          ", 0);
    // OLED_ShowString(2, 1, "music           ", 1);
    // OLED_ShowString(3, 1, "device          ", 0);
    // OLED_ShowString(4, 1, "return          ", 0);
}

/**
 * @brief 项
 * @param None
 * @retval None
 */
void gui_c(void)
{
    // OLED_ShowString(1, 1, "weater          ", 0);
    // OLED_ShowString(2, 1, "music           ", 0);
    // OLED_ShowString(3, 1, "device          ", 1);
    // OLED_ShowString(4, 1, "return          ", 0);
}

/**
 * @brief 项
 * @param None
 * @retval None
 */
void gui_d(void)
{
    // OLED_ShowString(1, 1, "weater          ", 0);
    // OLED_ShowString(2, 1, "music           ", 0);
    // OLED_ShowString(3, 1, "device          ", 0);
    // OLED_ShowString(4, 1, "return          ", 1);
}

/**
 * @brief 项
 * @param None
 * @retval None
 */
void gui_a_a(void)
{
    // OLED_ShowString(1, 1, "HangZhou        ", 1);
    // OLED_ShowString(2, 1, "BeiJing         ", 0);
    // OLED_ShowString(3, 1, "ShangHai        ", 0);
    // OLED_ShowString(4, 1, "return          ", 0);
}

/**
 * @brief 项
 * @param None
 * @retval None
 */
void gui_a_b(void)
{
    // OLED_ShowString(1, 1, "HangZhou        ", 0);
    // OLED_ShowString(2, 1, "BeiJing         ", 1);
    // OLED_ShowString(3, 1, "ShangHai        ", 0);
    // OLED_ShowString(4, 1, "return          ", 0);
}

/**
 * @brief 项
 * @param None
 * @retval None
 */
void gui_a_c(void)
{
    // OLED_ShowString(1, 1, "HangZhou        ", 0);
    // OLED_ShowString(2, 1, "BeiJing         ", 0);
    // OLED_ShowString(3, 1, "ShangHai        ", 1);
    // OLED_ShowString(4, 1, "return          ", 0);
}

/**
 * @brief 项
 * @param None
 * @retval None
 */
void gui_a_d(void)
{
    // OLED_ShowString(1, 1, "HangZhou        ", 0);
    // OLED_ShowString(2, 1, "BeiJing         ", 0);
    // OLED_ShowString(3, 1, "ShangHai        ", 0);
    // OLED_ShowString(4, 1, "return          ", 1);
}

/**
 * @brief 项
 * @param None
 * @retval None
 */
void gui_b_a(void)
{
    // OLED_ShowString(1, 1, "WindyHill       ", 1);
    // OLED_ShowString(2, 1, "New Boy         ", 0);
    // OLED_ShowString(3, 1, "Kiss The Rain   ", 0);
    // OLED_ShowString(4, 1, "return          ", 0);
}

/**
 * @brief 项
 * @param None
 * @retval None
 */
void gui_b_b(void)
{
    // OLED_ShowString(1, 1, "WindyHill       ", 0);
    // OLED_ShowString(2, 1, "New Boy         ", 1);
    // OLED_ShowString(3, 1, "Kiss The Rain   ", 0);
    // OLED_ShowString(4, 1, "return          ", 0);
}

/**
 * @brief 项
 * @param None
 * @retval None
 */
void gui_b_c(void)
{
    // OLED_ShowString(1, 1, "WindyHill       ", 0);
    // OLED_ShowString(2, 1, "New Boy         ", 0);
    // OLED_ShowString(3, 1, "Kiss The Rain   ", 1);
    // OLED_ShowString(4, 1, "return          ", 0);
}

/**
 * @brief 项
 * @param None
 * @retval None
 */
void gui_b_d(void)
{
    // OLED_ShowString(1, 1, "WindyHill       ", 0);
    // OLED_ShowString(2, 1, "New Boy         ", 0);
    // OLED_ShowString(3, 1, "Kiss The Rain   ", 0);
    // OLED_ShowString(4, 1, "return          ", 1);
}

/**
 * @brief 项
 * @param None
 * @retval None
 */
void gui_c_a(void)
{
    // OLED_ShowString(1, 1, "WiFi            ", 1);
    // OLED_ShowString(2, 1, "Sound           ", 0);
    // OLED_ShowString(3, 1, "Version         ", 0);
    // OLED_ShowString(4, 1, "return          ", 0);
}

/**
 * @brief 项
 * @param None
 * @retval None
 */
void gui_c_b(void)
{
    // OLED_ShowString(1, 1, "WiFi            ", 0);
    // OLED_ShowString(2, 1, "Sound           ", 1);
    // OLED_ShowString(3, 1, "Version         ", 0);
    // OLED_ShowString(4, 1, "return          ", 0);
}

/**
 * @brief 项
 * @param None
 * @retval None
 */
void gui_c_c(void)
{
    // OLED_ShowString(1, 1, "WiFi            ", 0);
    // OLED_ShowString(2, 1, "Sound           ", 0);
    // OLED_ShowString(3, 1, "Version         ", 1);
    // OLED_ShowString(4, 1, "return          ", 0);
}

/**
 * @brief 项
 * @param None
 * @retval None
 */
void gui_c_d(void)
{
    // OLED_ShowString(1, 1, "WiFi            ", 0);
    // OLED_ShowString(2, 1, "Sound           ", 0);
    // OLED_ShowString(3, 1, "Version         ", 0);
    // OLED_ShowString(4, 1, "return          ", 1);
}

/**
 * @brief 项
 * @param None
 * @retval None
 */
void gui_a_a_(void)
{
    // OLED_ShowString(1, 1, "HangZhou        ", 0);
    // OLED_ShowString(2, 1, "winding         ", 0);
    // OLED_ShowString(3, 1, "2020.5.5        ", 0);
    // OLED_ShowString(4, 1, "25C             ", 0);
}

/**
 * @brief 项
 * @param None
 * @retval None
 */
void gui_a_b_(void)
{
    // OLED_ShowString(1, 1, "BeiJing         ", 0);
    // OLED_ShowString(2, 1, "rain            ", 0);
    // OLED_ShowString(3, 1, "2020.5.5        ", 0);
    // OLED_ShowString(4, 1, "25C             ", 0);
}

/**
 * @brief 项
 * @param None
 * @retval None
 */
void gui_a_c_(void)
{
    // OLED_ShowString(1, 1, "ShangHai        ", 0);
    // OLED_ShowString(2, 1, "snowing         ", 0);
    // OLED_ShowString(3, 1, "2020.5.5        ", 0);
    // OLED_ShowString(4, 1, "25C             ", 0);
}

/**
 * @brief 项
 * @param None
 * @retval None
 */
void gui_b_a_(void)
{
    // OLED_ShowString(1, 1, "play WindyHill  ", 0);
    // OLED_ShowString(2, 1, "                ", 0);
    // OLED_ShowString(3, 1, "                ", 0);
    // OLED_ShowString(4, 1, "                ", 0);
}

/**
 * @brief 项
 * @param None
 * @retval None
 */
void gui_b_b_(void)
{
    // OLED_ShowString(1, 1, "play New Boy    ", 0);
    // OLED_ShowString(2, 1, "                ", 0);
    // OLED_ShowString(3, 1, "                ", 0);
    // OLED_ShowString(4, 1, "                ", 0);
}

/**
 * @brief 项
 * @param None
 * @retval None
 */
void gui_b_c_(void)
{
    // OLED_ShowString(1, 1, "play Kiss The Ra", 0);
    // OLED_ShowString(2, 1, "in              ", 0);
    // OLED_ShowString(3, 1, "                ", 0);
    // OLED_ShowString(4, 1, "                ", 0);
}

/**
 * @brief 项
 * @param None
 * @retval None
 */
void gui_c_a_(void)
{
    // OLED_ShowString(1, 1, "WiFi imformation", 0);
    // OLED_ShowString(2, 1, "                ", 0);
    // OLED_ShowString(3, 1, "                ", 0);
    // OLED_ShowString(4, 1, "                ", 0);
}

/**
 * @brief 项
 * @param None
 * @retval None
 */
void gui_c_b_(void)
{
    // OLED_ShowString(1, 1, "Sound:%40       ", 0);
    // OLED_ShowString(2, 1, "                ", 0);
    // OLED_ShowString(3, 1, "                ", 0);
    // OLED_ShowString(4, 1, "                ", 0);
}

/**
 * @brief 项
 * @param None
 * @retval None
 */
void gui_c_c_(void)
{
    // OLED_ShowString(1, 1, "Version 1.3     ", 0);
    // OLED_ShowString(2, 1, "                ", 0);
    // OLED_ShowString(3, 1, "                ", 0);
    // OLED_ShowString(4, 1, "                ", 0);
}

/**
 * @brief 菜单列表
 */
key_table_t table[] =
    {
        // 第0层
        {0, 1, 1, start_gui},

        // 第一层
        {1, 2, 5, gui_a},
        {2, 3, 9, gui_b},
        {3, 4, 13, gui_c},
        {4, 1, 0, gui_d},

        // 第二层
        {5, 6, 17, gui_a_a},
        {6, 7, 18, gui_a_b},
        {7, 8, 19, gui_a_c},
        {8, 5, 1, gui_a_d},

        {9, 10, 20, gui_b_a},
        {10, 11, 21, gui_b_b},
        {11, 12, 22, gui_b_c},
        {12, 9, 2, gui_b_d},

        {13, 14, 23, gui_c_a},
        {14, 15, 24, gui_c_b},
        {15, 16, 25, gui_c_c},
        {16, 13, 3, gui_c_d},

        // 第三层
        {17, 17, 5, gui_a_a_},
        {18, 18, 6, gui_a_b_},
        {19, 19, 7, gui_a_c_},

        {20, 20, 9, gui_b_a_},
        {21, 21, 10, gui_b_b_},
        {22, 22, 11, gui_b_c_},

        {23, 23, 13, gui_c_a_},
        {24, 24, 14, gui_c_b_},
        {25, 25, 15, gui_c_c_},
};

#endif
